﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace English_v2
{
    public partial class WordsConForm : Form
    {
        private System.IO.StreamReader wordsFile = null;
        bool streamEnd = false;
        int sentencesCount = 0;
        int boxesCount = 0;
        int correctCount = 0;
        TableLayoutPanel mainTable;
        
        public WordsConForm()
        {
            InitializeComponent();            
        }

        private void WordsConForm_Load(object sender, EventArgs e)
        {
            this.openStream();
            this.loadNextFile(sender, e);
        }

        private void openStream()
        {
            try
            {
                this.wordsFile = new System.IO.StreamReader(@"Files/words.txt");
            }
            catch (Exception e)
            {
                MessageBox.Show("Chyba pri otvarani suboru pre WordsConForm\n[" + e.Message + "]");
                this.quitOrRestart(this.quitFileMenu, null);
            }
        }

        private void loadNextFile(object sender, EventArgs e)
        {
            this.clearAll();
            this.notAllRight();
            string[] sentences;
            this.readNextBlock(out sentences);
            createMainTable(this.sentencesCount);
            createSentences(ref sentences);
        }

        private void clearAll()
        {
            this.boxesCount = 0;
            this.correctCount = 0;
            this.mainPanel.Controls.Clear();
        }

        private void notAllRight()
        {
            this.nextFileMenu.Enabled = false;
            this.nextTool.Enabled = false;
            this.nextContext.Enabled = false;
            this.correctMenu.Enabled = true;
            this.correctTool.Enabled = true;
            this.correctContext.Enabled = true;
        }

        private void readNextBlock(out string[] sentences)
        {
            this.streamEnd = false;
            try
            {
                sentences = new string[10];
                this.sentencesCount = 0;
                while ((this.sentencesCount < 10) && (!this.wordsFile.EndOfStream))
                {
                    sentences[this.sentencesCount] = this.wordsFile.ReadLine();
                    this.sentencesCount++;
                    if (this.wordsFile.EndOfStream)
                    {
                        this.streamEnd = true;
                    }
                }
            }
            catch(Exception e)
            {
                sentences = null;
                MessageBox.Show("Chyba pri citani suboru words.txt\n[" + e.Message + "]");
                this.quitOrRestart(this.quitFileMenu, null);
            }
        }

        private void createMainTable(int length)
        {
            this.mainTable = new TableLayoutPanel();
            this.mainTable.Parent = this.mainPanel;
            this.mainTable.Dock = DockStyle.Fill;
            this.mainTable.RowStyles.Clear();
            for (int i = 0; i < length; i++)
            {
                this.mainTable.RowStyles.Add(new RowStyle(SizeType.Percent, (int)((1/Double.Parse(length.ToString()))*100)));
            }
            this.mainTable.Visible = false;
        }

        private void createSentences(ref string[] sentences)
        {
            for (int i = 0; i < this.sentencesCount; i++)
            {
                string[] sentence = sentences[i].Split(';');
                TableLayoutPanel sentenceTable;
                this.createSentenceTable(sentence.Length, i, out sentenceTable); 
                for (int j = 0; j < sentence.Length; j++)
                {
                    if (j % 2 == 0)
                    {
                        this.parseWords(ref sentenceTable, ref sentence, j);
                    }
                    else
                    {
                        this.parseOptions(ref sentenceTable, ref sentence, j);
                    }
                }
            }
            this.mainTable.Visible = true;
        }

        private void createSentenceTable(int length, int row, out TableLayoutPanel sentenceTable)
        {
            sentenceTable = new TableLayoutPanel();
            sentenceTable.Parent = this.mainTable;
            this.mainTable.Controls.Add(sentenceTable, 0, row);
            sentenceTable.Dock = DockStyle.Fill;
            sentenceTable.RowStyles.Clear();
            for (int i = 0; i < length; i++)
            {
                sentenceTable.ColumnStyles.Add(new ColumnStyle(SizeType.Percent));
            }
        }

        private void parseWords(ref TableLayoutPanel sentenceTable, ref string[] sentence, int j)
        {
            Label text = this.parsedWords(ref sentence[j]);
            sentenceTable.Controls.Add(text, j, 0);
            sentenceTable.ColumnStyles[j].Width = (int)(System.Convert.ToDouble(text.Width) / System.Convert.ToDouble(sentenceTable.Width));
            text.Anchor = AnchorStyles.Left;
        }

        private Label parsedWords(ref string text)
        {
            Label label = new Label()
            {
                Text = text,
                AutoSize = true,
                TextAlign = ContentAlignment.MiddleLeft
            };
            label.Font = new Font(new FontFamily("Times New Roman"), 12, FontStyle.Italic);
            return label;
        }

        private void parseOptions(ref TableLayoutPanel sentenceTable, ref string[] sentence, int j)
        {
            this.boxesCount++;
            ComboBox box = this.parsedOptions(ref sentence[j]);
            sentenceTable.Controls.Add(box, j, 0);
            sentenceTable.ColumnStyles[j].Width = (int)(System.Convert.ToDouble(box.Width) / System.Convert.ToDouble(sentenceTable.Width));
            box.Anchor = AnchorStyles.Left;
        }

        private ComboBox parsedOptions(ref string options)
        {
            string[] parsedOps = options.Split('|');
            ComboBox box = new ComboBox()
            {
                Tag = parsedOps[0],
                FlatStyle = FlatStyle.System,
            };
            this.setBoxRandomly(ref box, ref parsedOps);
            this.setBoxGraphics(ref box);
            box.TextChanged += new EventHandler(this.controlCorrect);
            return box;
        }

        private void setBoxRandomly(ref ComboBox box, ref string[] parsedOps)
        {
            int arLength = parsedOps.Length;
            int[] sequence = new int[arLength];
            for (int i = 0; i < arLength; i++)
            {
                sequence[i] = i;               
            }          
            Random generator = new Random();
            sequence= sequence.OrderBy(x => generator.Next()).ToArray();
            for (int i = 0; i < arLength; i++)
            {
                box.Items.Add(parsedOps[sequence[i]]);
            }
        }

        private void setBoxGraphics(ref ComboBox box)
        {
            box.Font = new Font(new FontFamily("Times New Roman"), 10, FontStyle.Italic);
            int maxWidth = 0;
            foreach (var item in box.Items)
            {
                int actualWidth = TextRenderer.MeasureText(item.ToString(), box.Font).Width;
                if (actualWidth > maxWidth)
                {
                    maxWidth = actualWidth;
                }
            }
            box.Width = maxWidth + 22;
        }

        private void controlCorrect(object sender, EventArgs e)
        {
            ComboBox box= (ComboBox)sender;
            if (this.isCorrect(box))
            {
                this.correctAnswer(box);
            } else
            {
                this.wrongAnswer(box);
            }
        }

        private bool isCorrect(ComboBox box)
        {
            if (box.Text == box.Tag.ToString())
            {
                return true;
            }
            return false;
        }

        private void correctAnswer(ComboBox box)
        {
            box.DropDownStyle = ComboBoxStyle.Simple;
            box.KeyDown += new KeyEventHandler(this.readOnlyBox);
            box.Width = TextRenderer.MeasureText(box.Text, box.Font).Width+2;
            box.Height = 23;
            box.BackColor = Color.PaleGreen;
            this.mainTable.SelectNextControl(box, true, true, true, true);
            this.correctCount++;
            if (this.correctCount == this.boxesCount)
            {
                this.allRight();
            }
        }

        private void readOnlyBox(object sender, KeyEventArgs e)
        {
            e.SuppressKeyPress = true;
        }

        private void allRight()
        {
            this.nextFileMenu.Enabled = true;
            this.nextTool.Enabled = true;
            this.nextContext.Enabled = true;
            this.correctMenu.Enabled = false;
            this.correctTool.Enabled = false;
            this.correctContext.Enabled = false;
            if (this.streamEnd)
            {
                this.showEndDialog();
            }
        }

        private void showEndDialog()
        {
            EndDialogForm edf = new EndDialogForm() { MiniAppMode = "wordsForm" };
            this.DialogResult= edf.ShowDialog();
            this.Close();
        }

        private void wrongAnswer(ComboBox box)
        {
            box.BackColor = Color.LightSalmon;
        }

        private void showAnswers(object sender, EventArgs e)
        {
            foreach (Control mtc in this.mainTable.Controls)
            {
                if (mtc is TableLayoutPanel)
                {
                    foreach (Control stc in ((TableLayoutPanel)mtc).Controls)
                    {
                        if (stc is ComboBox)
                        {
                            ((ComboBox)stc).SelectedItem = null;
                            ((ComboBox)stc).Text = null;
                            ((ComboBox)stc).SelectedText = ((ComboBox)stc).Tag.ToString();
                        }
                    }
                }
            }
        }

        private void showTutorial(object sender, EventArgs e)
        {
            TutorialForm tutorial = new TutorialForm() { Page = 1 };
            tutorial.ShowDialog();
        }

        private void quitOrRestart(object sender, EventArgs e)
        {
            if(((ToolStripMenuItem)sender).Text=="Restart")
            {
                this.DialogResult = DialogResult.Retry;
            }
            this.Close();
        }
    }       
}
        
